所以,我只是在手动计算e
R中的值,我发现有些东西对我来说有点令人不安.
e
使用R exp()
命令的价值......
exp(1) #[1] 2.718282
现在,我将尝试使用手动计算它 x = 10000
x <- 10000 y <- (1 + (1 / x)) ^ x y #[1] 2.718146
不完全,但我们会尝试更接近使用 x = 100000
x <- 100000 y <- (1 + (1 / x)) ^ x y #[1] 2.718268
温暖但有点偏......
x <- 1000000 y <- (1 + (1 / x)) ^ x y #[1] 2.71828
现在,让我们尝试一个巨大的
x <- 5000000000000000 y <- (1 + (1 / x)) ^ x y #[1] 3.035035
嗯,那不对.这里发生了什么?我是否溢出数据类型并需要使用某个包?如果是这样,当您溢出数据类型时是否没有警告?
你的机器精度有问题.一旦(1 / x) <2.22e-16
,1 + (1 / x)
只是1.数学极限在有限精度数值计算中被破坏.x
问题的最后一点已经5e+15
非常接近这个边缘了.试试吧x <- x * 10
,你y
会的1
.
这既不是"溢出"也不是"下溢",因为表示一个小到的数字没有困难1e-308
.这是浮点运算期间丢失有效数字的问题.当你这样做时1 + (1 / x)
,越大x
,(1 / x)
当你将它添加到1时,可以保留该部分中的有效数字越少,并最终(1 / x)
完全失去该术语.
## valid 16 significant digits 1 + 1.23e-01 = 1.123000000000000| 1 + 1.23e-02 = 1.012300000000000| ... ... 1 + 1.23e-15 = 1.000000000000001| 1 + 1.23e-16 = 1.000000000000000|
任何数值分析书都会告诉你以下内容.
避免添加大量和少量数字.在浮点加法中a + b = a * (1 + b / a)
,如果b / a <2.22e-16
,那么我们a + b = a
.这意味着当累加多个正数时,从最小到最大累积它们会更稳定.
避免从相同幅度的另一个中减去一个数字,否则可能会出现取消错误.该网页有一个使用二次公式的经典示例.
你也被建议阅读关于常数"pi"的读数在50次迭代后没有变得更好,在你的问题后几天问了一个问题.使用一个近似无理数的系列在数值上是稳定的,因为你不会在你的问题中看到荒谬的行为.但是有限数量的有效有效数字会产生一个不同的问题:数值收敛,也就是说,您只能将目标值近似到一定数量的有效数字.MichaelChirico使用泰勒系列的答案将在19个术语之后收敛,因为1 / factorial(19)
当加到1时,已经在数字上为0.
浮点数之间的乘法/除法不会对有效数字造成问题; 它们可能导致"溢出"或"下溢".但是,考虑到可表示的浮点值范围很广(1e-308~1e + 307),"溢出"和"下溢"应该很少见.真正的困难在于加法/减法,其中有效数字很容易丢失.请参阅我可以在R中使用许多小值稳定地反转Vandermonde矩阵吗?有关矩阵计算的示例.获得更高的精度并非不可能,但工作可能更多.例如,矩阵示例的OP最终使用了GMP(GNU多精度算术库)和相关的R包来继续:如何将Rmpfr值放入R中的函数中?